﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace CustomizeControl
{
    public class CollapsiblePanel : Panel
    {
        private string _title_text = "Title";
        // 圆角的半径
        private int _radius = 3;
        // 标题所在区域的高度
        private int title_height = 24;
        //折叠后增加的高度
        private const int extra_height = 5;
        // 箭头尺寸
        private int arrow_size = 4;
        //是否展开
        private bool _expanded;
        private int _expandHeight;
        private Rectangle _headerBounds;


        public int CornerRadius
        {
            get { return _radius; }
            set { _radius = value; this.Invalidate(); }
        }

        [DefaultValue(false)]
        [Description("Collapses the control when set to true")]
        [Category("Material")]
        public bool Expanded
        {
            get => _expanded;
            set
            {
                _expanded = value;
                CollapseOrExpand();
                Invalidate();
            }
        }
        [Category("自定义外观")]
        [Description("标题文本")]
        public string TitleText
        {
            get => _title_text;
            set { _title_text = value; Invalidate(); }
        }

        [Category("Disposition")]
        [Description("Fires when Panel Collapse")]
        public event EventHandler PanelCollapse;

        [Category("Disposition")]
        [Description("Fires when Panel Expand")]
        public event EventHandler PanelExpand;

        public CollapsiblePanel()
        {
            SetStyle(ControlStyles.AllPaintingInWmPaint |
                 ControlStyles.UserPaint |
                 ControlStyles.ResizeRedraw |
                 ControlStyles.OptimizedDoubleBuffer |
                 ControlStyles.Opaque, true);
            UpdateRegion();

            Expanded = true;
            AutoScroll = false;
            Width = 200;
            Height = 100;
            Font = new Font("微软雅黑", 10.5F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(134)));
        }

        protected override void InitLayout()
        {
            LocationChanged += (sender, e) => { Parent?.Invalidate(); };
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            // 清除锯齿边缘残留
            e.Graphics.Clear(Parent.BackColor);
            // 不调用基类的OnPaint，完全自定义绘制
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            e.Graphics.PixelOffsetMode = PixelOffsetMode.Half;
            e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
            float radius = Math.Min(_radius, Math.Min(Width, Height) / 2); // 圆角半径上限

            using (var path = GetRoundRectPath(ClientRectangle, radius))
            {
                using (var brush = new SolidBrush(Color.White))
                {
                    e.Graphics.FillPath(brush, path);
                }
                // 填充上半部分颜色
                var topRect = new RectangleF(2.0f, 2.0f, Width - 4.0f, title_height);
                using (var topPath = CreateTopRoundPath(topRect, Math.Max(_radius - 0.5f, 0)))
                {
                    using (var topBrush = new SolidBrush(BackColor))
                    {
                        e.Graphics.FillPath(topBrush, topPath);
                    }
                }
                // 绘制标题文本
                using (var brush = new SolidBrush(Color.Black))
                {
                    e.Graphics.DrawString(_title_text, Font, brush, 30, 3);
                }
                //绘制箭头
                if (_expanded)
                {
                    Point center = new Point(20 - arrow_size, 14);
                    using (Pen arrowPen = new Pen(Color.White, 3))
                    {
                        arrowPen.CustomEndCap = new AdjustableArrowCap(arrow_size, arrow_size);
                        e.Graphics.DrawLine(arrowPen,
                            new Point(center.X, center.Y - arrow_size),
                            new Point(center.X, center.Y + arrow_size));
                    }
                }
                else
                {
                    Point center = new Point(20, 14);
                    using (Pen arrowPen = new Pen(Color.White, 3))
                    {
                        arrowPen.CustomEndCap = new AdjustableArrowCap(arrow_size, arrow_size);
                        e.Graphics.DrawLine(arrowPen,
                            new Point(center.X - arrow_size, center.Y),
                            new Point(center.X + arrow_size, center.Y));
                    }
                }
            }

            // 绘制边框（可选）
            using (var pen = new Pen(BackColor, 2))
            {
                using (var path = GetRoundRectPath(new RectangleF(2.0f, 2.0f, Width - 4.0f, Height - 4.0f), Math.Max(_radius - 0.5f, 0)))
                {
                    e.Graphics.DrawPath(pen, path);
                }
            }
        }

        private GraphicsPath GetRoundRectPath(RectangleF rect, float radius)
        {
            GraphicsPath path = new GraphicsPath();
            path.StartFigure();
            path.AddArc(rect.X, rect.Y, radius, radius, 180, 90);       // 左上角
            path.AddArc(rect.Right - radius, rect.Y, radius, radius, 270, 90);  // 右上角
            path.AddArc(rect.Right - radius, rect.Bottom - radius, radius, radius, 0, 90); // 右下角
            path.AddArc(rect.X, rect.Bottom - radius, radius, radius, 90, 90);  // 左下角
            path.CloseFigure();
            return path;
        }


        private GraphicsPath CreateTopRoundPath(RectangleF rect, float radius)
        {
            var path = new GraphicsPath();
            int diameter = 30;
            path.StartFigure();
            path.AddArc(rect.X, rect.Y, radius, radius, 180, 90);          // 左上
            path.AddArc(rect.Right - radius, rect.Y, radius, radius, 270, 90); // 右上
            path.AddLine(rect.Right, rect.Y + diameter, rect.Right, rect.Bottom);        // 右侧
            path.AddLine(rect.Right, rect.Bottom, rect.Left, rect.Bottom);            // 底部
            path.AddLine(rect.Left, rect.Bottom, rect.Left, rect.Y + diameter);          // 左侧
            path.CloseFigure();
            return path;
        }

        protected override void OnBackColorChanged(EventArgs e)
        {
            base.OnBackColorChanged(e);
            if (DesignMode)
            {
                Invalidate();  // 设计模式下立即刷新
            }
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            // 空实现：禁止绘制默认背景
        }

        private void UpdateRegion()
        {
            using (var path = GetRoundRectPath(ClientRectangle, _radius))
            {
                Region?.Dispose();
                Region = new Region(path);
            }
        }
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            if (_expanded)
            {
                if (DesignMode)
                {
                    _expandHeight = Height;
                }
                if (Height < title_height + extra_height)
                {
                    Height = title_height + extra_height;
                }
            }
            else
            {
                Height = title_height + extra_height;
            }
            _headerBounds = new Rectangle(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, title_height);

            UpdateRegion();
            Invalidate();
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            if (DesignMode)
            {
                return;
            }
            if (_headerBounds.Contains(e.Location))
            {
                Cursor = Cursors.Hand;
            }
            else
            {
                Cursor = Cursors.Default;
            }
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (DesignMode)
            {
                return;
            }
            if (Enabled && _headerBounds.Contains(e.Location))
            {
                _expanded = !_expanded;
                CollapseOrExpand();
            }

            base.OnMouseDown(e);
        }

        private void CollapseOrExpand()
        {
            if (_expanded)
            {
                this.Height = _expandHeight;
                if (PanelExpand != null)
                {
                    this.PanelExpand(this, new EventArgs());
                }
            }
            else
            {
                _expandHeight = this.Height;
                this.Height = title_height + extra_height;

                if (PanelCollapse != null)
                {
                    this.PanelCollapse(this, new EventArgs());
                }
            }
            Invalidate();
        }
    }
}
